//============================================================================
// Name        : GeneriekeAlgoritmen.cpp
// Author      : Pleun Willemsen en Walter Ebbers
// Version     : V1.0
// Copyright   : Your copyright notice
// Description : GeneriekeAlgoritmen opdracht 5 - Advanced C++
//============================================================================

#include <iostream>
#include <fstream>
#include <vector>
#include <iterator>
#include "Leerling.h"
#include <algorithm>
#include <functional>
#include <map>

using namespace std;
typedef vector<string> vString;

//multimap werkt hetzelfde al een map alleen kan je hiermee een key van meerdere values voorzien
multimap<string, Leerling*> leerlingenMap;
multimap<string, string> tempWaarde;

const int aantalBestanden = 3;
string bestanden[aantalBestanden] =
{ "a-e.txt", "f-k.txt", "l-z.txt" };

void maakLeerling(string i)
{
	multimap<string, string>::iterator p = tempWaarde.find(i);

	if (p == tempWaarde.end())
	{
		Leerling * l = new Leerling;
		l->setLeerlingWaarde(i);
		leerlingenMap.insert(make_pair(l->getKlas(), l));
		tempWaarde.insert(make_pair(i, i));
	}
}

bool same(string first, string second)
{
	return (string(first) == string(second));
}

string toXML(const std::pair<string, Leerling*>& data)
{
	return data.second->toString();
}

class KleinerDan
{
	public:
		bool operator ()(const string & s1, const string & s2)
		{
			return s1 < s2;
		}
};

int main()
{
	KleinerDan kd;
	cout << "Opdracht: Generieke Algoritmen" << endl;
	cout << "Door: Pleun Willemsen & Walter Ebbers" << endl;
	vString coll;
	vString::iterator i;

	for (int ii = 0; ii < aantalBestanden; ii++)
	{
		cout << bestanden[ii] << endl;

		ifstream Studenten(bestanden[ii].c_str());
		istream_iterator<string> eos; // end-of-stream iterator
		istream_iterator<string> iit(Studenten); // stdin iterator

		copy(iit, // start of source
		        eos, // end of source
		        back_inserter(coll)); // destination
		//sorteren op alfabet
		sort(coll.begin(), coll.end(), kd);

		// duplicaten opzoeken
		i = unique(coll.begin(), coll.end(), same);
		//resizen
		coll.erase(i, coll.end());
		coll.resize(i - coll.begin());

		//voor ieder serie waardes -> leerling maken
		for_each(coll.begin(), coll.end(), maakLeerling);
	}

	//Openen van een nieuw XML bestand
	ofstream newXml("Studenten.xml");
	//Iterator om te schrijven
	ostream_iterator<string> output(newXml);

	*output = "<studenten>";
	transform(leerlingenMap.begin(), leerlingenMap.end(), *output, toXML);
	*output = "</studenten>";

	cout << "Alle leerlingen staan nu in de 'Studenten.xml'. Te vinden in de root van het programma." << endl;

	return 0;

}
